package com.qlogic.commons.utils.json;

import java.util.ArrayList;
import java.util.List;

public class JsonArray implements JsonEntity {

	private static final long serialVersionUID = 5969290028072204587L;

	private List<Object> values;

	public JsonArray () {
	}

	public JsonArray (String json) throws JsonException {
		this (new JsonParser (json));
	}

	public JsonArray (JsonParser jt) throws JsonException {
		char c = jt.nextClean();
		char q;
		if (c == '[') {
			q = ']';
		} else if (c == '(') {
			q = ')';
		} else {
			throw jt.syntaxError("A JSONArray text must start with '['");
		}
		if (jt.nextClean() == ']') {
			return;
		}
		jt.back();
		for (;;) {
			if (jt.nextClean() == ',') {
				jt.back();
				add (JsonObject.NULL);
			} else {
				jt.back();
				add (jt.nextValue());
			}
			c = jt.nextClean();
			switch (c) {
			case ';':
			case ',':
				if (jt.nextClean() == ']') {
					return;
				}
				jt.back();
				break;
			case ']':
			case ')':
				if (q != c) {
					throw jt.syntaxError("Expected a '" + new Character(q)
							+ "'");
				}
				return;
			default:
				throw jt.syntaxError("Expected a ',' or ']'");
			}
		}
	}
	
	public int count () {
		if (values == null) {
			return 0;
		}
		return values.size ();
	}
	
	public void add (Object value) {
		if (values == null) {
			values = new ArrayList<Object> ();
		}
		values.add (value);
	}
	
	public void set (String name, Object value) {
		values.add (value);
	}

	public Object get (int index) {
		if (values == null) {
			return null;
		}
		return values.get (index);
	}

	public void clear () {
		if (values == null) {
			return;
		}
		
		for (int i = 0; i < count (); i++) {
			Object value = values.get (i);
			if (value instanceof JsonObject) {
				((JsonObject)value).clear ();
			} else if (value instanceof JsonArray) {
				((JsonArray)value).clear ();
			}
		}
		values.clear ();
		values = null;
		
	}
	
	public boolean isNull (int index) {
		return JsonObject.NULL.equals (get (index));
	}

    public String toString () {
        try {
            return '[' + join (",") + ']';
        } catch (Exception e) {
            return null;
        }
    }

    public String join (String separator) throws JsonException {
        int len = count ();
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < len; i += 1) {
            if (i > 0) {
                sb.append(separator);
            }
            sb.append (JsonObject.valueToString (get(i)));
        }
        String s = sb.toString();
        sb.setLength (0);
        sb = null;
        return s;
    }

    public String toString (int indentFactor) throws JsonException {
        return toString (indentFactor, 0);
    }

    String toString (int indentFactor, int indent) throws JsonException {
        int len = count ();
        if (len == 0) {
            return "[]";
        }
        int i;
        StringBuilder sb = new StringBuilder("[");
        if (len == 1) {
            sb.append (JsonObject.valueToString (get(0), indentFactor, indent));
        } else {
            int newindent = indent + indentFactor;
            sb.append('\n');
            for (i = 0; i < len; i += 1) {
                if (i > 0) {
                    sb.append(",\n");
                }
                for (int j = 0; j < newindent; j += 1) {
                    sb.append(' ');
                }
                sb.append(JsonObject.valueToString (get(i), indentFactor, newindent));
            }
            sb.append('\n');
            for (i = 0; i < indent; i += 1) {
                sb.append(' ');
            }
        }
        sb.append(']');
        String s = sb.toString();
        sb.setLength (0);
        sb = null;
        return s;
    }

}